package top.suyarong.ftbqsync.listener;

import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Location;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.*;
import top.suyarong.ftbqsync.timer.DataSyncTask;


import static org.bukkit.event.EventPriority.HIGHEST;
import static org.bukkit.event.EventPriority.LOWEST;

public class FTBQPreventListener implements Listener {

    public static final String WARN = "§c§l正在同步您的数据,同步完成前请勿操作/退出,以免出现进度回档";

    @EventHandler(priority = LOWEST)
    public void pre(AsyncPlayerChatEvent pEvent) {
        this.post(pEvent);
    }

    @EventHandler(ignoreCancelled = true, priority = HIGHEST)
    public void post(AsyncPlayerChatEvent pEvent) {
        this.handle(pEvent.getPlayer(), pEvent);
    }

    @EventHandler(priority = LOWEST)
    public void pre(EntityDamageEvent pEvent) {
        post(pEvent);
    }

    @EventHandler(ignoreCancelled = true, priority = HIGHEST)
    public void post(EntityDamageEvent pEvent) {
        if (pEvent.getEntity() instanceof Player) {
            this.handle((Player) pEvent.getEntity(), pEvent);
        }
    }

    @EventHandler(priority = LOWEST)
    public void pre(InventoryClickEvent pEvent) {
        post(pEvent);
    }

    @EventHandler(ignoreCancelled = true, priority = HIGHEST)
    public void post(InventoryClickEvent pEvent) {
        HumanEntity tWho = pEvent.getWhoClicked();
        if (tWho instanceof Player) {
            Player player = (Player) tWho;
            if (!DataSyncTask.isLock(player.getName())) return;
            pEvent.setCancelled(true);
            player.spigot().sendMessage(ChatMessageType.ACTION_BAR, new BaseComponent[]{new TextComponent(WARN)});
            tWho.closeInventory();
        }
    }

    @EventHandler(priority = LOWEST)
    public void pre(EntityPickupItemEvent pEvent) {
        this.post(pEvent);
    }

    @EventHandler(ignoreCancelled = true, priority = HIGHEST)
    public void post(EntityPickupItemEvent pEvent) {
        this.handle(pEvent.getEntity(), pEvent);
    }

    @EventHandler(priority = LOWEST)
    public void pre(PlayerDropItemEvent pEvent) {
        this.post(pEvent);
    }

    @EventHandler(ignoreCancelled = true, priority = HIGHEST)
    public void post(PlayerDropItemEvent pEvent) {
        this.handle(pEvent.getPlayer(), pEvent);
    }

    @EventHandler(priority = LOWEST)
    public void pre(PlayerInteractEntityEvent pEvent) {
        this.post(pEvent);
    }

    @EventHandler(ignoreCancelled = true, priority = HIGHEST)
    public void post(PlayerInteractEntityEvent pEvent) {
        this.handle(pEvent.getPlayer(), pEvent);
    }

    @EventHandler(priority = LOWEST)
    public void pre(PlayerInteractEvent pEvent) {
        this.post(pEvent);
    }

    @EventHandler(priority = HIGHEST)
    public void post(PlayerInteractEvent pEvent) {
        this.handle(pEvent.getPlayer(), pEvent);
    }

    @EventHandler(priority = LOWEST)
    public void pre(PlayerCommandPreprocessEvent pEvent) {
        this.post(pEvent);
    }

    @EventHandler(ignoreCancelled = true, priority = HIGHEST)
    public void post(PlayerCommandPreprocessEvent pEvent) {
        this.handle(pEvent.getPlayer(), pEvent);
    }

    @EventHandler(priority = LOWEST)
    public void pre(PlayerToggleSneakEvent pEvent) {
        this.post(pEvent);
    }

    @EventHandler(ignoreCancelled = true, priority = HIGHEST)
    public void post(PlayerToggleSneakEvent pEvent) {
        this.handle(pEvent.getPlayer(), pEvent);
    }

    @EventHandler
    public void handle(PlayerMoveEvent pEvent) {
        Player player = pEvent.getPlayer();
        String playerName = player.getName();
        if (DataSyncTask.isLock(playerName)) {
            player.spigot().sendMessage(ChatMessageType.ACTION_BAR, new BaseComponent[]{new TextComponent(WARN)});
            Location tFromLoc = pEvent.getFrom();
            Location tToLoc = pEvent.getTo();
            tFromLoc.setYaw(tToLoc.getYaw());
            tFromLoc.setPitch(tToLoc.getPitch());
            pEvent.setTo(tFromLoc);
        }
    }

    /**
     * 处理事件
     *
     * @param pPlayer 玩家UUID
     * @param pEvent  事件
     * @return 是否取消
     */
    protected boolean handle(LivingEntity pPlayer, Cancellable pEvent) {
        if (!(pPlayer instanceof Player)) return false;
        Player player = (Player) pPlayer;
        if (DataSyncTask.isLock(pPlayer.getName())) {
            pEvent.setCancelled(true);
            player.spigot().sendMessage(ChatMessageType.ACTION_BAR, new BaseComponent[]{new TextComponent(WARN)});
            return true;
        }
        return false;
    }

}
